package ir.assignments.four;

import ir.assignments.four.helpers.FileHelper;

import java.io.File;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;

public class MeasureSearchEffectiveness {

	public static void main(String[] args) {
		String[] queries = new String[] { "mondego", "machine learning", "software engineering", "security", "student affairs",
				                          "graduate courses", "Crista Lopes", "REST", "computer games", "information retrieval" };
		
		double totalScore = 0;
		for (String query : queries) {
			double score = getScore(query, false); // true = display search results, false = only display search scores
			double originalScore = getOriginalScore(query);
			double improvement = (originalScore != -1) ? getImprovement(originalScore, score) : -1;
			
			System.out.println(query + ": " + score + (improvement != -1 ? " (" + improvement + "%)" : ""));
			
			totalScore += score;
		}
		
		double average = totalScore / queries.length;
		double originalAverage = getOriginalScore("Average Score");
		double averageImprovement = (originalAverage != -1) ? getImprovement(originalAverage, average) : -1;
		
		System.out.println("");
		System.out.println("Average Score: " + average + (averageImprovement != -1 ? " (" + averageImprovement + "%)" : ""));
	}
	
	private static double getImprovement(double original, double newScore) {
		double improvement = (newScore - original);
		if (original > 0)
			improvement /= original;
		
		improvement *= 100.0;
		
		BigDecimal bd = new BigDecimal(improvement).setScale(2, RoundingMode.HALF_EVEN);
		return bd.doubleValue();
	}
	
	private static double getScore(String query, boolean printResults) {
		SearchFiles localSearch = null;
		
		try {
			GoogleSearcher google = new GoogleSearcher();
			localSearch = new SearchFiles("docIndexEnhanced");
			
			List<String> googleResults = google.getSearchResults(query, 5);
			List<String> localResults = localSearch.search(query, 0, 5).getUrls();
			
			if (printResults) {
				printResults("Google", query, googleResults, true);
				printResults("Local", query, localResults, false);
			}
			
			// Calculate NDCG@5
			return NDCG.getNDCG(localResults, googleResults, 5);
		}
		catch (Exception e) {
			e.printStackTrace();
		}
		finally {
			if (localSearch != null)
				localSearch.close();
		}
		
		return -1;
	}
	
	private static double getOriginalScore(String query) {
		try {
			File originalScores = new File("originalNDCG@5.txt");
			if (originalScores.exists()) {
				String content = FileHelper.readFile(originalScores, 0);
				String[] lines = content.split(FileHelper.lineSeparator);
				
				for (String line : lines) {
					if (line.startsWith(query)) {
						int startIndex = line.indexOf(":");
						if (startIndex > -1) {
							startIndex += 2;
							return Double.parseDouble(line.substring(startIndex));
						}
					}						
				}
			}
		}
		catch (Exception e) {
			e.printStackTrace();
		}
		
		return -1;
	}
	
	private static void printResults(String header, String query, List<String> results, boolean checkLocalExistance) {
		System.out.println(header + "(" + query + "):");
		int rank = 1;
		for (String result : results) {
			boolean existsLocal = false;
			if (checkLocalExistance) {
				existsLocal = checkDocStorage.check(result);
			}
			
			System.out.println(" " + rank + ": " + result + (checkLocalExistance ? " (crawled? " + existsLocal + ")" : ""));
			rank++;
		}
	}
}
